package roboSoccer;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

/**
 * The RoboSoccer class contains the Main method and also extends Java AWT
 * Component so that an instance of the class can draw the field in a frame.
 * Initializing an instance of the class also creates a new GameState object
 * which contains all components of a game. In the Main method, there is a loop
 * that calls update and draw on the game.
 * <p>
 * In addition, the application menus are implemented in this file as event
 * listening classes.
 * 
 * @author Ben Hopkins
 */
public class RoboSoccer extends Component {

	private static final long serialVersionUID = 1L;

	// this tracks various display settings
	GraphicsUnit gu;
	
	// is game paused?
	boolean paused;

	// game state object
	GameState game;

	/**
	 * Creates a GameState object for our game, and a GraphicsUnit to draw it.
	 */
	public RoboSoccer() {
		gu = new GraphicsUnit();
		paused = false;
	}
	
	public void newGame(int type) {
		// initialize the game variables
		RoboTeam[] teams = { new RoboTeam(0, 5), new RoboTeam(1, 5) };
		game = new GameState(teams, new FieldObject(new Vector(
				GraphicsUnit.fieldOffsetX + GraphicsUnit.fieldX / 2,
				GraphicsUnit.fieldOffsetY + GraphicsUnit.fieldY / 2)));

		switch(type)
		{
		case 1: game.setNXT();
		case 2: game.setSimulation();
		}
		
		
		// add the game to the graphics unit
		gu.setGame(game);
	}

	/**
	 * Calls GameState's update(), which retrieves the information from vision
	 * and runs the AI routines and robot commands.
	 */
	public void update() {
		game.update(); // this updates the positions of the game objects, does
		// AI routines, everything
	}

	/**
	 * When paint is called, the GraphicsUnit is passed the Graphics object so
	 * it can draw the field and objects according to specified settings in
	 * GraphicsUnit.
	 */
	public void paint(Graphics g) {
		// draw everything in the graphics unit
		gu.draw(g);
	}

	/**
	 * Used by Component to set the window size. It gets the static values for
	 * the size of the field from GraphicsUnit.
	 */
	public Dimension getPreferredSize() {
		// The size of our window is the size of the field
		return new Dimension(GraphicsUnit.totalX, GraphicsUnit.totalY);
	}

	/**
	 * The Main method initializes the frame, game, and menu items and then runs
	 * a loop calling update and draw on the game. The game here is an instance
	 * of the RoboSoccer class.
	 * 
	 * @param args
	 *            No args used.
	 */
	public static void main(String[] args) {
		// This makes the frame
		final JFrame frame = new JFrame("RoboSoccer");
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		final RoboSoccer game = new RoboSoccer();
		frame.add(game);
		
		// Here we create the menu bar and add all the menu options
		MenuBar mb = new MenuBar();

		// game menu
		Menu gameMenu = new Menu("Game");

		CheckboxMenuItem pause = new CheckboxMenuItem("Pause");
		pause.setState(false);
		pause.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				game.paused = !game.paused;
			}
		});
		gameMenu.add(pause);
		
		MenuItem exit = new MenuItem("Exit");
		exit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				System.exit(0);
			}
		});
		gameMenu.add(exit);

		// settings menu
		Menu settings = new Menu("Settings");

		CheckboxMenuItem labels = new CheckboxMenuItem("Labels");
		labels.setState(true);
		labels.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				game.gu.labelsFlag = !game.gu.labelsFlag;
				game.repaint();
			}
		});
		settings.add(labels);

		CheckboxMenuItem aiInfo = new CheckboxMenuItem("AI Info");
		aiInfo.setState(true);
		aiInfo.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				game.gu.aiInfo = !game.gu.aiInfo;
				game.repaint();
			}
		});
		settings.add(aiInfo);
		
		CheckboxMenuItem drawAll = new CheckboxMenuItem("Draw All");
		drawAll.setState(true);
		drawAll.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent e) {
				game.gu.drawAll = !game.gu.drawAll;
				game.repaint();
			}
		});
		settings.add(drawAll);

		// add all the menus to the menu bar then add it to the frame
		mb.add(gameMenu);
		mb.add(settings);
		frame.setMenuBar(mb);

		// pack the frame(sets size and arranges components), set it
		// to visible and we're good to go
		frame.pack();
		frame.setVisible(true);

		// selection box to choose the type of game
		SelectionBox select = new SelectionBox(frame);
		int type = select.type;
		select.dispose();
		
		// create the right kind of game according to select
		if(type != 0)
			game.newGame(type);
		else
			System.exit(0);
		
		// finally, here is our game loop
		while (true) {
			if(!game.paused){
				game.update();
			}
			game.repaint();
		}
	}

}
